home
diamond Go Premium
Data Engineering Path  ·  Airflow
Apache Airflow Logo

Action Operators — Cloud Provider Integration

⚡ Connecting Airflow to External Systems

Cloud Provider Operators

Operator Provider What It Does
S3CreateObjectOperator AWS Creates/uploads objects to S3
RedshiftSQLOperator AWS Executes SQL on Amazon Redshift
GlueJobOperator AWS Triggers AWS Glue ETL jobs
EmrAddStepsOperator AWS Submits steps to Amazon EMR clusters
BigQueryInsertJobOperator GCP Executes BigQuery SQL queries
DataprocSubmitJobOperator GCP Submits jobs to Google Dataproc
GCSToLocalFilesystemOperator GCP Downloads files from Google Cloud Storage
SnowflakeOperator Snowflake Executes SQL in Snowflake
DatabricksRunNowOperator Databricks Triggers existing Databricks jobs
SparkSubmitOperator Spark Submits Spark applications

AWS Example: S3 to Redshift Pipeline

from airflow.sdk import DAG
from airflow.providers.amazon.aws.operators.s3 import S3CreateObjectOperator
from airflow.providers.amazon.aws.transfers.s3_to_redshift import S3ToRedshiftOperator
from airflow.providers.amazon.aws.sensors.s3 import S3KeySensor
from datetime import datetime

with DAG("s3_to_redshift", schedule="@daily", start_date=datetime(2024, 1, 1)) as dag:

    # Wait for source file to arrive
    wait_for_file = S3KeySensor(
        task_id="wait_for_csv",
        bucket_name="raw-data-bucket",
        bucket_key="sales/{{ ds }}/sales_data.csv",
        aws_conn_id="aws_default",
        deferrable=True,           # Don't block a worker slot
    )

    # Copy from S3 to Redshift
    load_to_redshift = S3ToRedshiftOperator(
        task_id="load_to_redshift",
        schema="public",
        table="sales_staging",
        s3_bucket="raw-data-bucket",
        s3_key="sales/{{ ds }}/sales_data.csv",
        redshift_conn_id="redshift_default",
        aws_conn_id="aws_default",
        copy_options=["CSV", "IGNOREHEADER 1", "REGION 'us-east-1'"],
    )

    wait_for_file >> load_to_redshift

GCP Example: BigQuery Pipeline

from airflow.sdk import DAG
from airflow.providers.google.cloud.operators.bigquery import (
    BigQueryCreateEmptyDatasetOperator,
    BigQueryInsertJobOperator,
)
from datetime import datetime

with DAG("bigquery_pipeline", schedule="@daily", start_date=datetime(2024, 1, 1)) as dag:

    create_dataset = BigQueryCreateEmptyDatasetOperator(
        task_id="create_dataset",
        dataset_id="analytics",
        gcp_conn_id="google_cloud_default",
    )

    run_query = BigQueryInsertJobOperator(
        task_id="aggregate_sales",
        configuration={
            "query": {
                "query": """
                    SELECT
                        DATE(order_date) as order_day,
                        SUM(amount) as total_sales,
                        COUNT(*) as order_count
                    FROM `project.raw.orders`
                    WHERE DATE(order_date) = '{{ ds }}'
                    GROUP BY 1
                """,
                "useLegacySql": False,
                "destinationTable": {
                    "projectId": "my-project",
                    "datasetId": "analytics",
                    "tableId": "daily_sales_{{ ds_nodash }}",
                },
                "writeDisposition": "WRITE_TRUNCATE",
            }
        },
        gcp_conn_id="google_cloud_default",
    )

    create_dataset >> run_query
⚠️ Important
Always use Jinja templating ({{ ds }}, {{ ds_nodash }}, {{ execution_date }}) in your operators to make them idempotent. This ensures that re-running a DAG for a specific date always processes the correct data.
lock

This content is reserved for Premium Members.

Upgrade to Premium

Entity Details

Create New Item

help

Submit Technical Query

Have a question or run into an issue? Describe it below, upload an optional screenshot, and our engineering team will answer it!

image Attach image (optional)

Submit Feedback

build Free Developer Utility Free Tool
gavel

Privacy & Legal Disclaimer

1. Client-Side Browser Processing

All utility tools on DeepEngineerHub (including Image to PDF, Text Formatters, JSON Converters, and Encryptors) execute 100% locally within your client browser using WebAssembly and JavaScript. No uploaded images, text, or documents are transmitted, collected, or stored on remote servers.

2. Limitation of Liability ("As-Is" Provision)

Tools and services are provided free of charge for convenience and educational purposes "as-is" without warranties of any kind. DeepEngineerHub shall not be held liable for any data loss, formatting inconsistencies, or indirect damages resulting from tool usage.

3. Open Source & Third-Party Software

Certain utilities utilize open-source client libraries (such as jsPDF, Mermaid.js, Pyodide) licensed under MIT, Apache, or BSD open licenses. All intellectual property remains with their respective copyright holders.